﻿using System;
using System.Collections.Generic;
using System.Text;
using Fcdbas.Core.WCF.TransFile.Contracts.Enums;
using System.IO;
using Fcdbas.Core.WCF.TransFile.Service.Common;
using Fcdbas.Core.WCF.TransFile.Contracts.Models;
using System.Configuration;

namespace Fcdbas.Core.WCF.TransFile.Service.Working
{
    public class LoadFileWorker
    {
        private LoadFileInfoModel _Info;

        public LoadFileWorker(LoadFileInfoModel info)
        {
            _Info = info;
        }

        public LoadFileWorker()
        {
 
        }

        public LoadFileInfoModel UpLoad()
        {
            try
            {
                string folder = string.Empty;
                ExecuteResult temp = _Info.Result;
                if (_Info.IsClientBuilderPath)
                {
                    //folder = _Info.ClientBuilderPath;
                    folder = GetFolder();
                    if (!ValidateFolder(folder, false, ref temp))
                    {
                        _Info.Result = temp;
                        goto Complete;
                    }
                }
                else
                {
                    folder = Const.DefaultSpacePath;

                    if (!ValidateFolder(folder, true, ref temp))
                    {
                        _Info.Result = temp;
                        goto Complete;
                    }

                    //string typeFolder = GetFolder();

                    //folder = Path.Combine(folder, typeFolder);
                    folder = GetFolder();
                    if (!ValidateFolder(folder, false, ref temp))
                    {
                        _Info.Result = temp;
                        goto Complete;
                    }

                }



                //string filePath = Path.Combine(folder, string.Format("{0}{1}", _Info.FileName, _Info.Extension));
                string filePath = Path.Combine(folder, _Info.FileTitle);
                try
                {
                    using (FileStream stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                        stream.Seek(_Info.OffsetIndex, SeekOrigin.Current);
                        stream.Write(_Info.IncrementData, 0, (int)_Info.IncrementSize);
                        stream.Flush();
                    }
                    _Info.OffsetIndex += _Info.IncrementSize;
                    _Info.Result = _Info.OffsetIndex == _Info.FileSize ? ExecuteResult.AllComplete : ExecuteResult.IncrementComplete;
                }
                catch (Exception ex)
                {
                    _Info.Result = ExecuteResult.WriteFail;
                }
            }
            catch (Exception ex)
            {
                _Info.Result = ExecuteResult.Error;
            }

        Complete:
            _Info.IncrementData = null;
            GC.Collect();
            return _Info;
        }

        public LoadFileInfoModel DownLoad()
        {
            try
            {
                string folder = string.Empty;
                ExecuteResult temp = _Info.Result;

                folder = Const.DefaultSpacePath;

                if (!ValidateFolder(folder, true, ref temp))
                {
                    _Info.Result = temp;
                    goto Complete;
                }

                folder = GetFolder();
                if (!ValidateFolder(folder, false, ref temp))
                {
                    _Info.Result = temp;
                    goto Complete;
                }

                string filePath = Path.Combine(folder, _Info.FileTitle);
                if (!File.Exists(filePath))
                {
                    _Info.Result = ExecuteResult.FileNotExists;
                    goto Complete;
                }
                try
                {

                    using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
                    {
                        _Info.FileSize = stream.Length;
                        stream.Seek(_Info.OffsetIndex, SeekOrigin.Current);
                        long size = stream.Length - _Info.OffsetIndex >= _Info.IncrementSize ? _Info.IncrementSize : stream.Length - _Info.OffsetIndex;
                        _Info.IncrementSize = size;
                        byte[] buffer = new byte[_Info.IncrementSize];
                        stream.Read(buffer, 0, buffer.Length);
                        stream.Flush();
                        _Info.IncrementData = buffer;
                    }

                    //罗紫华\\a8e51fa7-d223-4be9-9994-4c1a387d0bb4\\U8TaskPro.log
                    //_Info.OffsetIndex += _Info.IncrementSize;
                    _Info.Result = _Info.OffsetIndex == _Info.FileSize ? ExecuteResult.AllComplete : ExecuteResult.IncrementComplete;
                }
                catch (Exception ex)
                {
                    _Info.Result = ExecuteResult.ReadFail;
                }
            }
            catch (Exception ex)
            {
                _Info.Result = ExecuteResult.Error;
            }

        Complete:
            GC.Collect();
            return _Info;
        }

        private bool ValidateFolder(string folder, bool isRoot, ref ExecuteResult result)
        {
            try
            {
                if (string.IsNullOrEmpty(folder))
                {
                    result = isRoot ? ExecuteResult.RootFolderNotFound : ExecuteResult.FolderFail;
                    return false;
                }
                else if (!Directory.Exists(folder))
                {
                    if (isRoot)
                    {
                        result = ExecuteResult.RootFolderNotFound;
                        return false;
                    }
                    else
                    {
                        Directory.CreateDirectory(folder);
                    }
                }
            }
            catch (Exception ex)
            {
                result = ExecuteResult.FolderFail;
                return false;
            }

            return true;
        }

        public CheckFileResult CheckFile()
        {
            CheckFileResult result = new CheckFileResult();
            try
            {
                string folder = GetFolder();
                //string filePath = Path.Combine(folder, string.Format("{0}{1}", _Info.FileName, _Info.Extension));
                string filePath = Path.Combine(folder, _Info.FileTitle);
                if (File.Exists(filePath))
                {
                    try
                    {
                        string newFileName =string.Format("{0}{1}", Guid.NewGuid().ToString(), _Info.Extension);
                        string backupPath = Path.Combine(folder, newFileName);
                        
                        FileManager.Move(filePath, backupPath);
                        result.IsBackup = true;
                        result.IsSuccess = true;
                        result.BackupFileName = newFileName;
                    }
                    catch { result.IsBackup = false; result.IsSuccess = false; }
                }
                else
                {
                    result.IsBackup = false;
                    result.IsSuccess = true;
                    result.BackupFileName = string.Empty;
                }
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
            }
            return result;
        }

        public GetOffSetResult GetFileOffSet(bool createNew)
        {
            GetOffSetResult result = new GetOffSetResult();
            try
            {
                //string folder = Const.DefaultSpacePath;
                //folder = Path.Combine(folder, GetFolder());

                string folder = GetFolder();
                //string filePath = Path.Combine(folder, string.Format("{0}{1}", _Info.FileName, _Info.Extension));
                string filePath = Path.Combine(folder, _Info.FileTitle);
                if (File.Exists(filePath))
                {
                    FileInfo fileInfo = new FileInfo(filePath);
                    result.IsSuccess = true;
                    result.OffSet = fileInfo.Length;
                    result.IsCreateNew = false;
                }
                else
                {
                    if (createNew)
                    {
                        File.Create(filePath);
                        result.IsSuccess = true;
                        result.OffSet = 0;
                    }
                    else
                    {
                        result.IsSuccess = true;
                        result.OffSet = -1;
                    }
                }
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.OffSet = -1;
            }
            return result;

        }

        public CheckFileResult DeleteFile()
        {
            CheckFileResult result = new CheckFileResult();
            try
            {
                //string folder = Const.DefaultSpacePath;
                //folder = Path.Combine(folder, GetTypeFolder());
                string folder = GetFolder();
                //string filePath = Path.Combine(folder, string.Format("{0}{1}", _Info.FileName, _Info.Extension));
                string filePath = Path.Combine(folder, _Info.FileTitle);
                
                //if (File.Exists(filePath))
                //{
                   // File.Delete(filePath);
                   // FileManager.Delete(filePath);
                //}
                result.IsSuccess = FileManager.Delete(filePath)==0;
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
            }
            return result;
        }

        public long GetDownLoadSize(SpaceType loadSpaceType, string customFolder, List<string> relativePaths)
        {
            long size = 0;
            string folder = GetFolder(loadSpaceType, customFolder);
            if (relativePaths != null && relativePaths.Count > 0)
            {
                foreach (string relativePath in relativePaths)
                {
                    string filePath = Path.Combine(folder, relativePath);
                    if (File.Exists(filePath))
                    {
                        FileInfo info = new FileInfo(filePath);
                        size += info.Length;
                    }
                }
            }
            return size;
        }

        public TransFilesResult MoveFile(TransFilesOnServerModel item)
        {
            TransFilesResult result = TransFilesResult.Fail;
            try
            {
                string originalPath = item.OriginalPath;
                string targetPath = item.TargetPath;
                string folder1 = GetFolder(item.OriginalSpaceType, item.OriginalCustomFolder);
                string folder2 = GetFolder(item.TargetSpaceType, item.TargetCustomFolder);
                string originalFullPath = Path.Combine(folder1, originalPath);
                string targetPathFullPath = Path.Combine(folder2, targetPath);
                if (File.Exists(originalFullPath))
                {
                    if (File.Exists(targetPathFullPath))
                    {
                        FileManager.Delete(targetPathFullPath);
                    }
                    string targetFolder = Path.GetDirectoryName(targetPathFullPath);
                    if (!Directory.Exists(targetFolder))
                    {
                        Directory.CreateDirectory(targetFolder);
                    }

                    FileManager.Move(originalFullPath, targetPathFullPath);
                    result = TransFilesResult.Success;
                }
                else
                {
                    result = TransFilesResult.FileNotFound;
                }
            }
            catch (Exception ex)
            {
                result = TransFilesResult.Fail;
            }
            return result;
        }

        public TransFilesResult CopyFile( TransFilesOnServerModel item)
        {
            TransFilesResult result = TransFilesResult.Fail;
            try
            {
                string originalPath = item.OriginalPath;
                string targetPath = item.TargetPath;
                string folder1 = GetFolder(item.OriginalSpaceType, item.OriginalCustomFolder);
                string folder2 = GetFolder(item.TargetSpaceType, item.TargetCustomFolder);
                string originalFullPath = Path.Combine(folder1, originalPath);
                string targetPathFullPath = Path.Combine(folder2, targetPath);
                if (File.Exists(originalFullPath))
                {
                    if (File.Exists(targetPathFullPath))
                    {
                        FileManager.Delete(targetPathFullPath);
                    }
                    FileManager.Copy(originalFullPath, targetPathFullPath);
                    result = TransFilesResult.Success;
                }
                else
                {
                    result = TransFilesResult.FileNotFound;
                }
            }
            catch (Exception ex)
            {
                result = TransFilesResult.Fail;
            }
            return result;
        }

        public TransFilesResult CheckFile(TransFilesOnServerModel item)
        {

            string originalPath = item.OriginalPath;
            string targetPath = item.TargetPath;
            string folder1 = GetFolder(item.OriginalSpaceType, item.OriginalCustomFolder);
            string folder2 = GetFolder(item.TargetSpaceType, item.TargetCustomFolder);
            string originalFullPath = Path.Combine(folder1, originalPath);
            string targetPathFullPath = Path.Combine(folder2, targetPath);

            if (!File.Exists(originalFullPath))
                return TransFilesResult.FileNotFound;

            if (File.Exists(targetPathFullPath))
                return TransFilesResult.FileExists;

            return TransFilesResult.Success;
        }

        public string GetFolder()
        {
            ///TODO: 获取配置的根路径
            string folder = string.Empty;
            if (_Info.IsClientBuilderPath)
            {
                folder = _Info.ClientBuilderPath;
            }
            else
            {
                string spaceTypePath =string.Empty;
                folder = GetFolder(_Info.UpLoadFileType, _Info.CustomFolder);
            }
            if (!Directory.Exists(folder))
                Directory.CreateDirectory(folder);
            return folder;
        }

        private string GetFolder(SpaceType loadSpaceType, string customFolder)
        {
            ///TODO:实现读取文件位置
            string rootFolder = AppDomain.CurrentDomain.BaseDirectory;

            return Path.Combine(rootFolder, customFolder);
        }
    }
}
